﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Windows.Forms;
using System.Data;

namespace SoketYaMaHa
{
    public class SoketYaMaHa
    {
        public static string Devicename = "";
        public SoketYaMaHa(string Devicename_)
        {
            Devicename = Devicename_;
        }
        #region YaMaHa通信
        //使用IPv4地址，流式socket方式，tcp协议传递数据
        Socket soketsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        public string recstr;
        int reclen;
        static int count = 0;
        A.BLL.newsContent content1 = new A.BLL.newsContent();
        bool Isconnetion = false;
        /// <summary>
        /// 发送命令
        /// </summary>
        /// <param name="str">命令字符串</param>
        /// <returns></returns>
        public string Gocmd(string str)//命令执行
        {
            try
            {
                byte[] buffer = Encoding.UTF8.GetBytes(str + Environment.NewLine);
                recstr = "";
                if (Isconnetion)
                {
                    soketsend.Send(buffer);
                }
                TimeSpan timeSpanstart = new TimeSpan(DateTime.Now.Ticks);
                while (!recstr.Contains("A1") && !IsInt(recstr))
                {
                    TimeSpan timeSpanstop = new TimeSpan(DateTime.Now.Ticks);
                    TimeSpan ts = timeSpanstart.Subtract(timeSpanstop).Duration();
                    if (ts.Seconds > 3)
                    {
                        count++;
                        if (count < 2)//第一次发送失败后执行第二次发送
                        {
                            recstr = Gocmd(str);
                            continue;
                        }
                        if (!soketsend.Connected)
                        {
                            recstr = "断开";
                        }
                        recstr = "超时";
                        break;
                    }
                }
            }
            catch (Exception err)
            {
               CsLogFun.WriteToLog(err);
               MessageBox.Show("提示：机器人发送失败" );
            }
            return recstr;
        }
        #region //转化数据
        /// <summary>
        /// 十六进制字符串转化为字节数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static byte[] HexStringToByteArray(string s)
        {
            try
            {
                s = s.Replace(" ", "");
                byte[] buffer = new byte[s.Length / 2];
                for (int i = 0; i < s.Length; i += 2)
                    buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
                return buffer;
            }
            catch (Exception err)
            {
                CsLogFun.WriteToLog(err);
                throw new Exception("提示：" + err.Message);
            }

        }
        /// <summary>
        /// 从汉字转换到16进制
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string GetHexFromChs(string s)
        {
            //if ((s.Length % 2) != 0)
            //{
            //    s += " ";//空格
            //}
            try
            {
                System.Text.Encoding chs = System.Text.Encoding.GetEncoding("gb2312");
                byte[] bytes = chs.GetBytes(s);
                string str = "";
                for (int i = 0; i < bytes.Length; i++)
                {
                    str += string.Format("{0:X}", bytes[i]);
                }
                str = "02 " + str + " 03";
                return str;
            }
            catch (Exception err)
            {
                CsLogFun.WriteToLog(err);
                throw new Exception("提示：" + err.Message);
            }

        }
        //汉字转Unicode编码
        protected string GetUnicode(string source)
        {
            try
            {
                byte[] bytes = Encoding.Unicode.GetBytes(source);
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < bytes.Length; i += 2)
                {
                    stringBuilder.AppendFormat("\\u{0}{1}", bytes[i + 1].ToString("x").PadLeft(2, '0'), bytes[i].ToString("x").PadLeft(2, '0'));
                }
                return stringBuilder.ToString();
            }
            catch (Exception err)
            {
                CsLogFun.WriteToLog(err);
                throw new Exception("提示：" + err.Message);
            }

        }
        //Unicode转汉字
        protected string Unicode2String(string source)
        {
            return new Regex(@"\\u([0-9A-F]{4})", RegexOptions.IgnoreCase | RegexOptions.Compiled).Replace(
                         source, x => string.Empty + Convert.ToChar(Convert.ToUInt16(x.Result("$1"), 16)));
        }
        #endregion     
        public bool SoketConnetion(string ServerIP, string ServerPoint) //建立soket连接
        {
            try
            {
                //连接到服务器,已经连接无需再连
                if (!soketsend.Connected)
                {
                    //连接到的目标IP
                    IPAddress ip_ = IPAddress.Parse(ServerIP);
                    //连接到目标IP的哪个应用(端口号！)
                    IPEndPoint point_ = new IPEndPoint(ip_, int.Parse(ServerPoint));
                    soketsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    soketsend.Connect(point_);
                    //设置缓存区容量
                    //soketsend.ReceiveBufferSize = 1024;
                    //soketsend.SendBufferSize = 1024 * 1024;
                    Thread th = new Thread(ReceiveMsg);
                    th.IsBackground = true;
                    th.Start();
                }
                if (soketsend.Connected)
                {
                    Isconnetion = true;
                }
            }
            catch (Exception err)
            {
                 CsLogFun.WriteToLog(err);
                 MessageBox.Show("提示：机器人连接失败，" + err.Message);
                 return false;
                //throw;
            }
            return Isconnetion;
        }
        void ReceiveMsg()//接受服务器端返回数据信息
        {
            string strre = "";
            while (true)
            {
                Thread.Sleep(1);
                try
                {
                    if (soketsend.Connected)
                    {
                        reclen = 0;
                        byte[] buffer = new byte[1024];
                        if (soketsend.Connected)
                            reclen = soketsend.Receive(buffer);
                        strre = Encoding.UTF8.GetString(buffer, 0, reclen);
                        if (reclen > 0 && strre.Contains("A1") == true)
                        {
                            recstr = "A1";
                        }
                        else if (reclen > 0)
                        {
                            CsLogFun.WriteToLog("接收到机器人数据：" + strre);
                            strre = strre.Replace("\r\n", "").Trim();
                            strre = strre.Replace("OK", "").Trim();
                            if (IsInt(strre))
                            {
                                recstr = strre;
                            }
                        }
                        strre = "";
                    }
                }
                catch (Exception err)
                {
                    Thread.Sleep(2000);
                    //CsLogFun.WriteToLog(err);
                    //MessageBox.Show("提示：机器人连接失败，" + err.ToString());
                    //throw;
                }
            }
        }
        #endregion
        public static bool IsInt(string str) //接收一个string类型的参数,保存到str里
        {
            if (str == null || str.Length == 0)    //验证这个参数是否为空
                return false;                           //是，就返回False
            ASCIIEncoding ascii = new ASCIIEncoding();//new ASCIIEncoding 的实例
            byte[] bytestr = ascii.GetBytes(str);         //把string类型的参数保存到数组里
            foreach (byte c in bytestr)                   //遍历这个数组里的内容
            {
                if (c < 48 || c > 57)                          //判断是否为数字
                {
                    return false;                              //不是，就返回False
                }
            }
            return true;                                        //是，就返回True
        }
    }
}
